use std::collections::HashMap;
use std::rc::Rc;
use chrono::Local;
use crate::business::websocket::dto::im_message_dto::MessageObject;
use crate::db::dao::im_group_dao::query_group_by_group_code;
use crate::db::dao::im_message_dao::{message_deletes, message_inserts, message_updates, query_message_by_server_id};
use crate::db::dao::im_session_dao::{session_get_by_group_code_and_user_id, session_get_by_user_id, session_insert, session_updates};
use crate::db::dao::im_user_dao::query_user_by_user_id;
use crate::db::db::Db;
use crate::db::pojo::pojo::{ImMessage, ImMessageStatus, ImSession};

pub struct SaveMessageService;

impl SaveMessageService {

    pub fn save_messages(user_id: String, message_objects: Vec<MessageObject>, _is_syn_message: bool) -> Vec<ImMessage> {
        let mut messages = message_objects.into_iter()
            .map(|message_object| {
                let mut message : ImMessage = message_object.into();
                message.current_user_id = user_id.clone();
                message
            })
            .collect::<Vec<ImMessage>>();

        let mut message_insert_list = Vec::new();
        let mut message_update_list = vec![];
        let mut message_delete_list = vec![];
        let mut session_update_list = vec![];

        let mut hot_message = HashMap::new();

        let db = Db::open();

        for message in messages.iter_mut() {
            let session = SaveMessageService::get_session(db.clone(), &message);
            log::info!("session_data, {:?}", session);
            match session {
                None => {
                    let mut new_session = SaveMessageService::build_session(db.clone(), &user_id, &message);
                    *hot_message.entry(new_session.id.clone().unwrap()).or_insert(0) += 1;

                    session_insert(db.clone(), &mut new_session);
                    message.session_id = new_session.id.unwrap();
                    message.session = Some(new_session);
                    log::info!("message session_id: {}", message.session_id);
                }
                Some(mut session) => {
                    *hot_message.entry(session.id.clone().unwrap()).or_insert(session.hot_message_total) += 1;
                    
                    session.hot_message_total = hot_message.get(&session.id.clone().unwrap()).unwrap().clone();
                    
                    message.session_id = session.id.unwrap();
                    message.session = Some(session.clone());
                    
                    log::info!("message session22: {:?}", session);

                    session.lately_message = message.content.clone();
                    session.update_time = Local::now();

                    session_update_list.push(session);
                }
            }

            let db_message = query_message_by_server_id(db.clone(), &user_id, &message.server_id.clone().unwrap());
            match db_message {
                None => {
                    message_insert_list.push(message);
                }
                Some(db_message) => {
                    match &message.status {
                        ImMessageStatus::Withdraw | ImMessageStatus::Updated => { message_update_list.push(message); }
                        ImMessageStatus::Delete => { message_delete_list.push(message); }
                        _ => {
                            log::info!("客户端不应该收到这个消息，messageId: {}, currentUserId: {}", db_message.id.unwrap(), user_id);
                        }
                    }
                }
            }
        }

        message_inserts(db.clone(), &mut message_insert_list);
        message_updates(db.clone(), &mut message_update_list);
        message_deletes(db.clone(), user_id.clone(), message_delete_list);

        let mut session_update_list2 = vec![];
        for session in session_update_list.iter_mut() {
            let size = hot_message.get(&session.id.clone().unwrap_or(0)).unwrap();
            session.hot_message_total = size.clone();
            session_update_list2.push(&mut *session);
        }
        session_updates(db.clone(), &mut session_update_list2);

        message_insert_list.iter().map(|message| (**message).clone()).collect::<Vec<ImMessage>>()
    }

    pub fn get_session(db: Db, message: &ImMessage)-> Option<ImSession> {
        log::info!("get session, {:?}", message);
        match &message.group_code {
            None => {
                session_get_by_user_id(db.clone(), &message.current_user_id, &message.from_user_id, &message.to_user_id.clone().unwrap())
            }
            Some(group_code) => {
                session_get_by_group_code_and_user_id(db.clone(), &group_code, &message.current_user_id)
            }
        }
    }

    pub fn build_session(db: Db, user_id: &String, message: &ImMessage) -> ImSession {
        match &message.group_code {
            None => {
                let mut to_user_id = message.to_user_id.clone().unwrap();
                if &to_user_id == user_id {
                    to_user_id = message.from_user_id.clone();
                }
                let to_user = query_user_by_user_id(db.clone(), &to_user_id);
                ImSession::build_by_user(user_id.clone(), Rc::new(to_user.unwrap()))
            }
            Some(group_code) => {
                let group = query_group_by_group_code(db.clone(), group_code);
                ImSession::build_by_group(user_id.clone(), Rc::new(group.unwrap()))
            }
        }
    }
}